package com.jt.resource.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.access.AccessDeniedHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 资源服务器的配置，在这个对象中重点要实现：
 * 1)JWT令牌解析的配置(客户端带着令牌访问资源时，要对令牌进行解析)
 * 2)启动资源访问的授权配置(不是所有登陆用户可以访问所有资源)
 */
@Configuration
@EnableResourceServer //此注解会启动资源服务器的默认配置
@EnableGlobalMethodSecurity(prePostEnabled = true) //执行方法之前启动权限检查
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Autowired
    private TokenStore tokenStore;
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        //super.configure(resources);
        //定义令牌生成策略，这里不是要创建令牌，是要解析令牌
        resources.tokenStore(tokenStore);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        //super.configure(http);
        //1.关闭跨域攻击
        http.csrf().disable();
        //2.放行所有资源的访问(对资源的访问不做认证)
        http.authorizeRequests().anyRequest().permitAll();
        http.exceptionHandling()
                .accessDeniedHandler(accessDeniedHandler());
    }
    @Bean
    public AccessDeniedHandler accessDeniedHandler(){
        return new AccessDeniedHandler() {
            @Override
            public void handle(HttpServletRequest httpServletRequest,
                               HttpServletResponse httpServletResponse,
                               AccessDeniedException e)
                               throws IOException, ServletException {
                //构建响应数据
                Map<String, Object> map = new HashMap<>();
                //将响应数据写到客户端
                map.put("state",HttpServletResponse.SC_FORBIDDEN);
                map.put("message","没有权限");
                //将响应数据写到客户端
                httpServletResponse.setCharacterEncoding("utf-8");

            }
        };
    }
}
